// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.util.ArrayList;
// import java.util.List;
#pragma once
#include "SQLObjectImpl.h"
#include "SQLReplaceable.h"

class SQLOver_WindowingType
{
public:
  static SQLOver_WindowingType_ptr ROWS;
  static SQLOver_WindowingType_ptr RANGE;

  string_ptr name;
  string_ptr nameLCase;
  uint64_t mask;

  SQLOver_WindowingType(uint64_t mask, string_ptr name);
};

class SQLOver_WindowingBound
{
public:
  static SQLOver_WindowingBound_ptr UNBOUNDED_PRECEDING;
  static SQLOver_WindowingBound_ptr PRECEDING;
  static SQLOver_WindowingBound_ptr CURRENT_ROW;
  static SQLOver_WindowingBound_ptr FOLLOWING;
  static SQLOver_WindowingBound_ptr UNBOUNDED_FOLLOWING;

  string_ptr name;
  string_ptr nameLCase;
  uint64_t mask;

  SQLOver_WindowingBound(uint64_t mask, string_ptr name);
};

class SQLOver : virtual public SQLObjectImpl, virtual public SQLReplaceable
{
public:
  SQLExpr_list_ptr partitionBy;
  SQLOrderBy_ptr orderBy;
  SQLOrderBy_ptr distributeBy;
  SQLOrderBy_ptr sortBy;
  SQLOrderBy_ptr clusterBy;

  // for db2
  SQLName_ptr of;

  SQLOver_WindowingType_ptr windowingType;

  BOOL_ptr windowingPreceding;
  BOOL_ptr windowingFollowing;

  SQLExpr_ptr windowingBetweenBegin;
  SQLOver_WindowingBound_ptr windowingBetweenBeginBound;

  SQLExpr_ptr windowingBetweenEnd;
  SQLOver_WindowingBound_ptr windowingBetweenEndBound;

  BOOL_ptr excludeCurrentRow;

  SQLOver();

  SQLOver(SQLOrderBy_ptr orderBy);

  SHAREDOBJECT(SQLOver);
  // @Override
  void accept0(SQLASTVisitor_ptr visitor);

  SQLOrderBy_ptr getOrderBy();

  void setOrderBy(SQLOrderBy_ptr x);

  SQLOrderBy_ptr getClusterBy();

  void setClusterBy(SQLOrderBy_ptr x);

  SQLOrderBy_ptr getDistributeBy();

  void setDistributeBy(SQLOrderBy_ptr x);

  SQLOrderBy_ptr getSortBy();

  void setSortBy(SQLOrderBy_ptr x);

  SQLName_ptr getOf();

  void setOf(SQLName_ptr of);

  SQLExpr_list_ptr getPartitionBy();

  SQLOver_WindowingType_ptr getWindowingType();

  void setWindowingType(SQLOver_WindowingType_ptr windowingType);

  BOOL_ptr isWindowingPreceding();

  void setWindowingPreceding(BOOL_ptr windowingPreceding);

  SQLExpr_ptr getWindowingBetweenBegin();

  void setWindowingBetweenBegin(SQLExpr_ptr windowingBetweenBegin);

  SQLExpr_ptr getWindowingBetweenEnd();

  void setWindowingBetweenEnd(SQLExpr_ptr windowingBetweenEnd);

  BOOL_ptr isWindowingBetweenEndPreceding();

  BOOL_ptr isWindowingBetweenEndFollowing();

  SQLOver_WindowingBound_ptr getWindowingBetweenBeginBound();
  void setWindowingBetweenBeginBound(SQLOver_WindowingBound_ptr windowingBetweenBeginBound);

  SQLOver_WindowingBound_ptr getWindowingBetweenEndBound();

  void setWindowingBetweenEndBound(SQLOver_WindowingBound_ptr windowingBetweenEndBound);

  BOOL_ptr isExcludeCurrentRow();

  void setExcludeCurrentRow(BOOL_ptr excludeCurrentRow);

  // @Override
  bool equals(Object_ptr o);

  // @Override
  int hashCode();

  void cloneTo(SQLOver_ptr x);

  SQLObject_ptr clone();

  // @Override
  BOOL_ptr replace(SQLExpr_ptr expr, SQLExpr_ptr target);
};
